package com.mycode.finance.service.impl;

import com.mycode.finance.entity.*;
import com.mycode.finance.mapper.*;
import com.mycode.finance.service.RiskPreferenceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 风险偏好服务实现类
 * 实现风险偏好分析算法
 */
@Service
public class RiskPreferenceServiceImpl implements RiskPreferenceService {

  @Autowired
  private RiskPreferenceMapper riskPreferenceMapper;

  @Autowired
  private UserTermFinancialMapper userTermFinancialMapper;

  @Autowired
  private UserChangeMoneyMapper userChangeMoneyMapper;

  @Autowired
  private UserFundProductMapper userFundProductMapper;

  @Autowired
  private LoanMapper loanMapper;

  @Autowired
  private FundProductMapper fundProductMapper;

  @Autowired
  private UserMapper userMapper;

  @Autowired
  private UserPayMoneyMapper userPayMoneyMapper;

  /**
   * 根据用户ID查询风险偏好
   * 
   * @param userId 用户ID
   * @return 风险偏好对象
   */
  @Override
  public RiskPreference selectByUserId(Integer userId) {
    return riskPreferenceMapper.selectByUserId(userId);
  }

  /**
   * 分析用户风险偏好
   * 基于资产百分比的风险评估模型
   * 
   * @param userId 用户ID
   * @return 风险偏好对象
   */
  @Override
  public RiskPreference analyzeUserRiskPreference(Integer userId) {
    // 计算用户总资产
    BigDecimal totalAssets = calculateTotalAssets(userId);

    // 初始化风险评分
    int score = 0;

    // 初始化各类资产金额
    BigDecimal lowRiskAmount = BigDecimal.ZERO; // 低风险资产(定期理财、货币基金)
    BigDecimal mediumRiskAmount = BigDecimal.ZERO; // 中风险资产(债券基金、部分混合基金)
    BigDecimal highRiskAmount = BigDecimal.ZERO; // 高风险资产(股票基金、高风险混合基金)

    // 投资产品类型集合(用于计算分散度)
    Set<String> productTypes = new HashSet<>();

    // 1. 分析定期理财产品（低风险）
    UserTermFinancialExample termExample = new UserTermFinancialExample();
    termExample.createCriteria().andUseridEqualTo(userId);
    List<UserTermFinancial> termList = userTermFinancialMapper.selectByExample(termExample);
    if (termList != null && !termList.isEmpty()) {
      score += 1; // 定期理财为低风险，基础分1分
      productTypes.add("定期理财");

      // 累计定期理财金额
      for (UserTermFinancial term : termList) {
        if (term.getProfit() != null) {
          lowRiskAmount = lowRiskAmount.add(term.getProfit());
        }
      }
    }

    // 2. 分析零钱理财产品（中低风险）
    UserChangeMoneyExample changeExample = new UserChangeMoneyExample();
    changeExample.createCriteria().andUseridEqualTo(userId);
    List<UserChangeMoney> changeList = userChangeMoneyMapper.selectByExample(changeExample);
    if (changeList != null && !changeList.isEmpty()) {
      score += 2; // 零钱理财为中低风险，基础分2分
      productTypes.add("零钱理财");

      // 累计零钱理财金额
      for (UserChangeMoney change : changeList) {
        if (change.getProfit() != null) {
          lowRiskAmount = lowRiskAmount.add(change.getProfit());
        }
      }
    }

    // 3. 分析基金产品（根据类型区分风险）
    UserFundProductExample fundExample = new UserFundProductExample();
    fundExample.createCriteria().andUseridEqualTo(userId);
    List<UserFundProduct> fundList = userFundProductMapper.selectByExample(fundExample);
    if (fundList != null && !fundList.isEmpty()) {
      for (UserFundProduct userFund : fundList) {
        FundProduct fund = fundProductMapper.selectByPrimaryKey(userFund.getFundid());
        if (fund != null) {
          String type = String.valueOf(fund.getType());
          BigDecimal amount = userFund.getProfit();

          if (type != null && amount != null) {
            if (type.equals("3")) { // 货币型基金
              score += 2; // 货币基金，基础分2分
              lowRiskAmount = lowRiskAmount.add(amount);
              productTypes.add("货币基金");
            } else if (type.equals("2")) { // 债券型基金
              score += 3; // 债券基金，基础分3分
              mediumRiskAmount = mediumRiskAmount.add(amount);
              productTypes.add("债券基金");
            } else if (type.equals("4")) { // 混合型基金
              score += 4; // 混合基金，基础分4分
              mediumRiskAmount = mediumRiskAmount.add(amount);
              productTypes.add("混合基金");
            } else if (type.equals("1")) { // 股票型基金
              score += 5; // 股票基金，基础分5分
              highRiskAmount = highRiskAmount.add(amount);
              productTypes.add("股票基金");
            } else {
              score += 3; // 其他类型基金，默认基础分3分
              mediumRiskAmount = mediumRiskAmount.add(amount);
              productTypes.add("其他基金");
            }
          }
        }
      }
    }

    // 计算各类资产占比
    double lowRiskRatio = 0;
    double mediumRiskRatio = 0;
    double highRiskRatio = 0;

    if (totalAssets.compareTo(BigDecimal.ZERO) > 0) {
      lowRiskRatio = lowRiskAmount.divide(totalAssets, 4, BigDecimal.ROUND_HALF_UP).doubleValue();
      mediumRiskRatio = mediumRiskAmount.divide(totalAssets, 4, BigDecimal.ROUND_HALF_UP).doubleValue();
      highRiskRatio = highRiskAmount.divide(totalAssets, 4, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    // 基于投资比例评分
    // 低风险产品比例评分
    if (lowRiskRatio > 0.8) {
      score += 0;
    } else if (lowRiskRatio > 0.5) {
      score += 1;
    } else if (lowRiskRatio > 0.3) {
      score += 2;
    } else {
      score += 3;
    }

    // 中风险产品比例评分
    if (mediumRiskRatio > 0.5) {
      score += 2;
    } else if (mediumRiskRatio > 0.3) {
      score += 1;
    }

    // 高风险产品比例评分
    if (highRiskRatio > 0.5) {
      score += 5;
    } else if (highRiskRatio > 0.3) {
      score += 3;
    } else if (highRiskRatio > 0.1) {
      score += 2;
    }

    // 投资分散度评分
    int productTypeCount = productTypes.size();
    if (productTypeCount >= 6) {
      score += 3;
    } else if (productTypeCount >= 4) {
      score += 2;
    } else if (productTypeCount >= 2) {
      score += 1;
    }

    // 4. 分析贷款情况
    LoanExample loanExample = new LoanExample();
    loanExample.createCriteria().andLoanidEqualTo(userId);
    List<Loan> loanList = loanMapper.selectByExample(loanExample);

    BigDecimal totalLoanAmount = BigDecimal.ZERO;
    if (loanList != null && !loanList.isEmpty()) {
      for (Loan loan : loanList) {
        // 累计贷款总额
        if (loan.getAmount() != null) {
          totalLoanAmount = totalLoanAmount.add(loan.getAmount());
        }

        // 贷款期限评分
        Integer term = loan.getTerm();
        if (term != null) {
          if (term <= 12) {
            score += 2; // 短期贷款（1年以内），加2分
          } else if (term <= 36) {
            score += 1; // 中期贷款（1-3年），加1分
          }
          // 长期贷款不加分
        }
      }
    }

    // 贷款金额与总资产比例评分
    double loanAssetRatio = 0;
    if (totalAssets.compareTo(BigDecimal.ZERO) > 0) {
      loanAssetRatio = totalLoanAmount.divide(totalAssets, 4, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    if (loanAssetRatio > 0.5) {
      score += 3;
    } else if (loanAssetRatio > 0.3) {
      score += 2;
    } else if (loanAssetRatio > 0.1) {
      score += 1;
    }

    // 根据总分确定风险偏好类别
    String riskLevel;
    if (score <= 3) {
      riskLevel = "保守型";
    } else if (score <= 6) {
      riskLevel = "稳健型";
    } else if (score <= 9) {
      riskLevel = "平衡型";
    } else if (score <= 12) {
      riskLevel = "进取型";
    } else {
      riskLevel = "激进型";
    }

    // 查询是否已有风险偏好记录
    RiskPreference riskPreference = riskPreferenceMapper.selectByUserId(userId);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String currentTime = sdf.format(new Date());

    if (riskPreference == null) {
      // 创建新记录
      riskPreference = new RiskPreference();
      riskPreference.setUserId(userId);
      riskPreference.setScore(score);
      riskPreference.setRiskLevel(riskLevel);
      riskPreference.setCreateTime(currentTime);
      riskPreference.setUpdateTime(currentTime);
      insertRiskPreference(riskPreference);
    } else {
      // 更新记录
      riskPreference.setScore(score);
      riskPreference.setRiskLevel(riskLevel);
      riskPreference.setUpdateTime(currentTime);
      updateRiskPreference(riskPreference);
    }

    return riskPreference;
  }

  /**
   * 计算用户总资产
   * 
   * @param userId 用户ID
   * @return 总资产金额
   */
  private BigDecimal calculateTotalAssets(Integer userId) {
    BigDecimal totalAssets = BigDecimal.ZERO;

    // 1. 获取用户账户余额 - 用户表中没有余额字段，暂时不计算

    // 2. 获取定期理财总额 - 使用profit字段
    UserTermFinancialExample termExample = new UserTermFinancialExample();
    termExample.createCriteria().andUseridEqualTo(userId);
    List<UserTermFinancial> termList = userTermFinancialMapper.selectByExample(termExample);
    if (termList != null) {
      for (UserTermFinancial term : termList) {
        if (term.getProfit() != null) {
          totalAssets = totalAssets.add(term.getProfit());
        }
      }
    }

    // 3. 获取零钱理财总额 - 使用profit字段
    UserChangeMoneyExample changeExample = new UserChangeMoneyExample();
    changeExample.createCriteria().andUseridEqualTo(userId);
    List<UserChangeMoney> changeList = userChangeMoneyMapper.selectByExample(changeExample);
    if (changeList != null) {
      for (UserChangeMoney change : changeList) {
        if (change.getProfit() != null) {
          totalAssets = totalAssets.add(change.getProfit());
        }
      }
    }

    // 4. 获取基金投资总额 - 使用profit字段
    UserFundProductExample fundExample = new UserFundProductExample();
    fundExample.createCriteria().andUseridEqualTo(userId);
    List<UserFundProduct> fundList = userFundProductMapper.selectByExample(fundExample);
    if (fundList != null) {
      for (UserFundProduct fund : fundList) {
        if (fund.getProfit() != null) {
          totalAssets = totalAssets.add(fund.getProfit());
        }
      }
    }

    // 5. 获取工资理财总额 - 使用profit字段
    UserPayMoneyExample payExample = new UserPayMoneyExample();
    payExample.createCriteria().andUseridEqualTo(userId);
    List<UserPayMoney> payList = userPayMoneyMapper.selectByExample(payExample);
    if (payList != null) {
      for (UserPayMoney pay : payList) {
        if (pay.getProfit() != null) {
          totalAssets = totalAssets.add(pay.getProfit());
        }
      }
    }

    return totalAssets;
  }

  /**
   * 插入风险偏好记录
   * 
   * @param riskPreference 风险偏好对象
   * @return 影响行数
   */
  @Override
  public int insertRiskPreference(RiskPreference riskPreference) {
    return riskPreferenceMapper.insertSelective(riskPreference);
  }

  /**
   * 更新风险偏好记录
   * 
   * @param riskPreference 风险偏好对象
   * @return 影响行数
   */
  @Override
  public int updateRiskPreference(RiskPreference riskPreference) {
    return riskPreferenceMapper.updateByPrimaryKeySelective(riskPreference);
  }
}